home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / hydrabbsa8 / source / src.lha / control / Control_Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-08  |  55.1 KB  |  1,936 lines

  1. /*
  2.  
  3.    HBBS (C) 1995 Hydra/LSD - All Rights Reserved!
  4.  
  5.    If you are reading this source and make *ANY* change or fix or whatever
  6.    then please send a copy to me at the following address...
  7.  
  8.    D.Clifton, 9 Shires Copse, Southbourne, Bournemouth, Dorset, BH6 4AL, ENGLAND!
  9.  
  10.    All Suggestions are most welcome as if *you* think something needs changing
  11.    then it probably does,  this program is supposed to be designed for the
  12.    user, not the programmer of it!!
  13.  
  14.    Thanks..
  15.  
  16.    Note: if you want a better KS3.0 only version then #define KS30 otherwise #define KS20..
  17.    and if you want to run cpr on the node program then #define DEBUGNODE
  18. */
  19.  
  20.  
  21. /*
  22.  
  23.   create linked list of TimeAccessData at startup
  24.  
  25. */
  26.  
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <time.h>
  32.  
  33. #include <exec/types.h>
  34. #include <exec/memory.h>
  35. #include <dos/dos.h>
  36. #include <dos/dostags.h>
  37. #include <dos/dosextens.h>
  38. #include <dos/filehandler.h>
  39. #include <intuition/screens.h>
  40. #include <intuition/intuition.h>
  41. #include <intuition/gadgetclass.h>
  42. #include <libraries/locale.h>
  43. #include <libraries/reqtools.h>
  44. #include <libraries/gadtools.h>
  45. #include <diskfont/diskfont.h>
  46. #include <utility/utility.h>
  47. #include <graphics/gfxbase.h>
  48. #include <graphics/scale.h>
  49. #include <workbench/workbench.h>
  50. #include <clib/locale_protos.h>
  51. #include <clib/exec_protos.h>
  52. #include <clib/wb_protos.h>
  53. #include <clib/intuition_protos.h>
  54. #include <clib/gadtools_protos.h>
  55. #include <clib/graphics_protos.h>
  56. #include <clib/utility_protos.h>
  57. #include <clib/diskfont_protos.h>
  58. #include <clib/alib_protos.h>
  59. #include <clib/dos_protos.h>
  60. #include <clib/reqtools_protos.h>
  61.  
  62. #include <wb2cli.h>  /* for the correct PATH settings when run from WB */
  63.  
  64.  
  65. UBYTE *versionstr="$VER: HBBS 0.8 (1.1.1996)";
  66.  
  67. #ifdef __SASC
  68. int CXBRK(void) { return(0); }
  69. int _CXBRK(void) { return(0); }
  70. void chkabort(void) {}
  71. #endif
  72.  
  73. #include "ControlGUI.h" // gui prototypes and external variables.
  74.  
  75. /* Main Stuff! */
  76.  
  77. #define MAIN
  78.  
  79. #include "/common/types.h"
  80. #include "/common/defines.h"
  81. #include "/common/errors.h"
  82. #include "/common/files.h"
  83. #include "/common/options.h"
  84. #include "/common/structures.h"
  85. #include "/common/strings.h"
  86.  
  87. #include "/library/hbbscommon_protos.h"
  88. #include "/library/hbbscommon_pragmas.h"
  89.  
  90. struct ReqToolsBase *ReqToolsBase;
  91. extern struct DosLibrary *DOSBase;
  92. struct Window *OldWindowPtr;
  93. struct Screen *Scr=NULL;
  94. struct Library *HBBSCommonBase=NULL;
  95.  
  96. char StatusText[80];
  97.  
  98. UWORD CtrlScrnCoolPens[]=
  99. {
  100.   0+8,1+8,1+8,2+8,1+8,3+8,2+8,0+8,2+8,1+8,2+8,1+8,65535
  101. };
  102.  
  103. /*
  104.   DETAILPEN,0+8,
  105.   BLOCKPEN,1+8,
  106.   TEXTPEN,1+8,
  107.   SHINEPEN,2+8,
  108.   SHADOWPEN,1+8,
  109.   FILLPEN,3+8,
  110.   FILLTEXTPEN,2+8,
  111.   BACKGROUNDPEN,0+8,
  112.   HIGHLIGHTTEXTPEN,2+8,
  113.   BARDETAILPEN,1+8,
  114.   BARBLOCKPEN,2+8,
  115.   BARTRIMPEN,1+8,
  116.  
  117. #define DETAILPEN        (0x0000)
  118. #define BLOCKPEN         (0x0001)
  119. #define TEXTPEN          (0x0002)
  120. #define SHINEPEN         (0x0003)
  121. #define SHADOWPEN        (0x0004)
  122. #define FILLPEN          (0x0005)
  123. #define FILLTEXTPEN      (0x0006)
  124. #define BACKGROUNDPEN    (0x0007)
  125. #define HIGHLIGHTTEXTPEN (0x0008)
  126. #define BARDETAILPEN     (0x0009)
  127. #define BARBLOCKPEN      (0x000A)
  128. #define BARTRIMPEN       (0x000B)
  129.  
  130.  
  131.  
  132. */
  133.  
  134. UWORD ColourArray[]=
  135. {
  136.   0x0000,
  137.   0x0F00,
  138.   0x00F0,
  139.   0x0FF0,
  140.   0x000F,
  141.   0x0F0F,
  142.   0x00FF,
  143.   0x0FFF,
  144.   0x0999,
  145.   0x0000,
  146.   0x0FFF,
  147.   0x057A,
  148. };
  149.  
  150. // global vars
  151.  
  152. UWORD offx;
  153. UWORD offy;
  154. WORD last_x=0;
  155. WORD last_y=0;
  156. LONG last_sec=0;
  157. LONG last_mic=0;
  158.  
  159. BOOL CfgOpen=FALSE;
  160.  
  161. struct Process *CtrlProc=NULL;
  162. struct BBSGlobalData *BBSGlobal=NULL;
  163. struct TextFont *HBBSFont;
  164.  
  165.  
  166. #ifdef KS20
  167. UWORD LastNodeClicked=0;  //due to GT_GetGadgetAttrs() being V39+ only we have to
  168.                           // make a note of the last node number clicked on in
  169.                           // the Nodes Listview! Argh!
  170. UWORD LastCycleClicked=0; // (and in the List Cycle Gadget Clicked..)
  171. #endif
  172.  
  173. //defines for struct BBSGlobalData
  174.  
  175. UBYTE *FILE_SCRMODEPREFS           = "HBBS:System/Data/CtrlScrPrefs.CFG";
  176.  
  177. UBYTE *OPT_BBS_BBSName             = "BBSName",
  178.       *OPT_BBS_BBSSerial           = "BBSSerial",
  179.       *OPT_BBS_BBSLocation         = "BBSLocation",
  180.       *OPT_BBS_BBSCountry          = "BBSCountry",
  181.       *OPT_BBS_BBSGroup            = "BBSGroup",
  182.       *OPT_BBS_BBSNodes            = "BBSNodes",
  183.       *OPT_BBS_SysopAccount        = "SysopAccount",
  184.       *OPT_BBS_Drive               = "Drive",
  185.       *OPT_BBS_BBSDrive            = "BBSDrive",
  186.       *OPT_BBS_MinFreeSpace        = "MinFreeSpace",
  187.       *OPT_BBS_NoFreeSpaceScript   = "NoFreeSpaceScript",
  188.       *OPT_BBS_ButtonName          = "ButtonName",
  189.       *OPT_BBS_ButtonCMD           = "ButtonCMD",
  190.       *OPT_BBS_HideScreen          = "HideScreen",
  191.       *OPT_BBS_ErrorLogFile        = "ErrorLogFile",
  192.       *OPT_BBS_ScrModeID           = "ScrModeID",
  193.       *OPT_BBS_ScrWidth            = "ScrWidth",
  194.       *OPT_BBS_ScrHeight           = "ScrHeight",
  195.       *OPT_BBS_ScrDepth            = "ScrDepth",
  196.       *OPT_BBS_UserDataFileName    = "UserDataFileName",
  197.       *OPT_BBS_NewUserAccessLevel  = "NewUserAccessLevel",
  198.       *OPT_BBS_MaxUsernameAttempts = "MaxUsernameAttempts",
  199.       *OPT_BBS_MaxPasswordAttempts = "MaxPasswordAttempts",
  200.       *OPT_BBS_MinPasswordLength   = "MinPasswordLength",
  201.       *OPT_BBS_LanguageName        = "LanguageName",
  202.       *OPT_BBS_LanguageExtn        = "LanguageExtn",
  203.       *OPT_BBS_EditorCMD           = "EditorCMD",
  204.       *OPT_BBS_CopyBufferSize      = "CopyBufferSize";
  205.  
  206. UBYTE *OPT_CONFL_Conferences       = "Conferences",
  207.       *OPT_CONFL_ConfPath          = "ConfPath",
  208.       *OPT_CONFL_NewUserConf       = "NewUserConf";
  209.  
  210. UBYTE *OPT_CONF_ConfName           = "ConfName",
  211.       *OPT_CONF_ConfActive         = "ConfActive",
  212.       *OPT_CONF_ConfAccess         = "ConfAccess",
  213.       *OPT_CONF_HoldFileList       = "HoldFileList",
  214.       *OPT_CONF_HoldFiles          = "HoldFiles",
  215.       *OPT_CONF_BadFileList        = "BadFileList",
  216.       *OPT_CONF_BadFiles           = "BadFiles",
  217.       *OPT_CONF_PartUpload         = "PartUpload",
  218.       *OPT_CONF_FileList           = "FileList",
  219.       *OPT_CONF_Upload             = "Upload",
  220.       *OPT_CONF_Download           = "Download",
  221.       *OPT_CONF_MaxDIZLines        = "MaxDIZLines",
  222.       *OPT_CONF_MenuPrompt         = "MenuPrompt",
  223.       *OPT_CONF_AutoMailScan       = "AutoMailScan",
  224.       *OPT_CONF_ConfPassWD         = "ConfPassWD",
  225.       *OPT_CONF_UserAllowed        = "UserAllowed";
  226.  
  227. UBYTE *OPT_LLIST_LEVEL             = "Level",
  228.       *OPT_LLIST_LEVELNAME         = "Level_Name";
  229.  
  230. #include "/common/Shared.c"
  231.  
  232. extern UWORD    CtrlScrndefpens;
  233.  
  234. extern UWORD   CtrlScrnColors[];
  235.  
  236. void About( void )
  237. {
  238.   char buffer[1024];
  239.  
  240.   sprintf(buffer,"HydraBBS %s (C) 1995 Deluxe Software Ltd.\n\n"
  241. #ifdef BETA
  242.                  "BETA VERSION, DO NOT SPREAD!\n\n"
  243. #endif
  244.                  "HBBS is a cool BBS System programed with users and sysops in mind\n"
  245.                  "unlike the ageing LAmiExpress which it is designed to replace.\n\n"
  246.                  "This software is SHAREWARE, if you use it then send a registration\n"
  247.                  "fee of £20 (UK Pounds Sterling) made Payable to D.Clifton\n\n"
  248.                  "To Deluxe Software Ltd, 9 Shires Copse, Bournemouth, Dorset, BH6 4AL, ENGLAND\n\n"
  249.                  "And you'll receive telephone support and the FULL Source Code, *and*\n"
  250.                  "you'll get all the updates and new doors programmed by as and when they\n"
  251.                  "are released.  See the docs for more info!\n\n"
  252.                  "Note: NOTHING IS DISABLED OR CUT-DOWN THIS ISTHE FULL THING!\n",versionstr);
  253.   HBBS_rterror(buffer);
  254. }
  255.  
  256. void PrintList( struct List *list)
  257. {
  258.   struct Node *node;
  259.   for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
  260.   {
  261.     puts(node->ln_Name);
  262.   }
  263. }
  264.  
  265.  
  266.  
  267. BOOL AllNodesShut( void )
  268. {
  269.   short NodesShut=0;
  270.   struct NodeData *nd;
  271.   for (nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd = (struct NodeData*)nd->node.ln_Succ)
  272.   {
  273.     if (nd->Status==STAT_CLOSED) NodesShut++;
  274.   }
  275.   if (NodesShut==BBSGlobal->BBSNodes) return(TRUE);
  276.   return(FALSE);
  277. }
  278.  
  279. struct Screen *OpenCtrlScrn(void)
  280. {
  281.   struct Screen *NewScr;
  282.  
  283.   if (NewScr=OpenScreenTags(NULL,    (SA_Title),(ULONG)"HBBS Main Control Screen (C) 1995 Hydra of LSD!",
  284.     (SA_PubName),(ULONG)str_CtrlScrnName,
  285.     (SA_Left)    ,0,
  286.     (SA_Top)     ,0,
  287.     (SA_Width)   ,BBSGlobal->ScrWidth,
  288.     (SA_Height)  ,BBSGlobal->ScrHeight,
  289.     (SA_DisplayID),BBSGlobal->ScrModeID,
  290.     (SA_Depth)   ,BBSGlobal->ScrDepth,
  291.     (SA_Overscan),1,
  292.     (SA_Font),(ULONG)&HBBS8066,
  293.     (SA_Behind),1,
  294.     (SA_Quiet),0,
  295.     (SA_ShowTitle),1,
  296.     (SA_AutoScroll),1,
  297.     (SA_FullPalette),1,
  298. //    (SA_ErrorCode),(ULONG)(&CtrlScrnError),
  299.     (SA_Pens), BBSGlobal->ScrDepth<4 ? (ULONG)&CtrlScrndefpens : (ULONG)&CtrlScrnCoolPens,
  300.     (SA_Colors),(ULONG)CtrlScrnColors,
  301.     (TAG_DONE)))
  302.   {
  303.     if (BBSGlobal->ScrDepth>=4)
  304.     {
  305.       LoadRGB4(&NewScr->ViewPort,ColourArray,12);
  306.       SetAPen(&NewScr->RastPort,8);
  307.       Flood(&NewScr->RastPort,1,0,NewScr->WBorTop+4);
  308.     }
  309.   }
  310.   return(NewScr);
  311. }
  312.  
  313. BOOL PickScreen( void )
  314. {
  315.   BOOL retval=FALSE;
  316.   struct rtScreenModeRequester *scrmodereq;
  317.  
  318.   if (scrmodereq = rtAllocRequestA (RT_SCREENMODEREQ, NULL))
  319.   {
  320.     if (rtScreenModeRequest (scrmodereq, "Select Screen mode:",RTSC_Flags,SCREQF_GUIMODES | SCREQF_DEPTHGAD | SCREQF_SIZEGADS,
  321.                                                                RT_Window,Ctrl,
  322.                                                                RTSC_MinHeight,200,
  323.                                                                RTSC_MinWidth,640,
  324.                                                                RTSC_MinDepth,2,
  325.                                                                RTSC_MaxDepth,4,
  326.  
  327.                                                                TAG_END))
  328.     {
  329.       BBSGlobal->ScrModeID=scrmodereq->DisplayID;
  330.       BBSGlobal->ScrHeight=scrmodereq->DisplayHeight;
  331.       BBSGlobal->ScrWidth=scrmodereq->DisplayWidth;
  332.       BBSGlobal->ScrDepth=scrmodereq->DisplayDepth;
  333.       retval=TRUE;
  334.     }
  335.     rtFreeRequest(scrmodereq);
  336.   }
  337.   return(retval);
  338. }
  339.  
  340. BOOL LoadScreenPrefs( void )
  341. {
  342.   struct CfgFileData *ScrCfg;
  343.   BOOL OK=FALSE;
  344.  
  345.   if (ScrCfg=HBBS_LoadConfig(FILE_SCRMODEPREFS,LCFG_NONE))
  346.   {
  347.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScrModeID,VTYPE_BIGNUM,OPT_BBS_ScrModeID,OPT_SINGLE))
  348.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScrHeight,VTYPE_BIGNUM,OPT_BBS_ScrHeight,OPT_SINGLE))
  349.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScrWidth,VTYPE_BIGNUM,OPT_BBS_ScrWidth,OPT_SINGLE))
  350.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScrDepth,VTYPE_BIGNUM,OPT_BBS_ScrDepth,OPT_SINGLE)) OK=TRUE;
  351.  
  352.     HBBS_FlushConfig(ScrCfg);
  353.   }
  354.   else
  355.   {
  356.     HBBS_rterror("Use the \"Select_Mode\" Utility to setup a screenmode!");
  357.   }
  358.   return(OK);
  359. }
  360.  
  361. void SaveScreenPrefs( void )
  362. {
  363.   struct CfgFileData *ScrCfg;
  364.   char params[30];
  365.   if (ScrCfg=HBBS_CreateConfig((FILE_SCRMODEPREFS)))
  366.   {
  367.     sprintf(params,"%d",BBSGlobal->ScrModeID);
  368.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrModeID,params);
  369.     sprintf(params,"%d",BBSGlobal->ScrHeight);
  370.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrHeight,params);
  371.     sprintf(params,"%d",BBSGlobal->ScrWidth);
  372.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrWidth,params);
  373.     sprintf(params,"%d",BBSGlobal->ScrDepth);
  374.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrDepth,params);
  375.  
  376.     if (!HBBS_SaveConfig(ScrCfg))
  377.     {
  378.       HBBS_rterror("Error Saving Screenmode Prefs!");
  379.     }
  380.     HBBS_FlushConfig(ScrCfg);
  381.   }
  382. }
  383.  
  384. void UpdateInfoLists( void )
  385. {
  386.   struct NodeData *nd;
  387.  
  388.   // *?* should we set gadgetatrs() the cycle gadget just to make sure.. ?
  389.  
  390.  
  391.   // set the list to be BLANK
  392.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,NULL,TAG_DONE);
  393.  
  394.   if (nd=HBBS_NodeDataPtr(LastNodeClicked)) // code contains number of listview selected
  395.   {
  396.     if ((nd->Status==STAT_ONLINE) || (nd->Status==STAT_READY))
  397.     {
  398.       switch (LastCycleClicked)
  399.       {
  400.         case 0: // Last Callers
  401.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Callers,TAG_DONE);
  402.           break;
  403.         case 1: // Last Downloads
  404.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Downloads,TAG_DONE);
  405.           break;
  406.         case 2: // Last Uploads
  407.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Uploads,TAG_DONE);
  408.           break;
  409.         case 3: // Last Pagers
  410.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Pagers,TAG_DONE);
  411.           break;
  412.         case 4: // Last Fails
  413.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_PWFails,TAG_DONE);
  414.           break;
  415.         case 5: // Last Carrier
  416.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Carrier,TAG_DONE);
  417.           break;
  418.       }
  419.     }
  420.   }
  421. }
  422.  
  423. void updategadgets( void )
  424. {
  425.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Labels,BBSGlobal->NodeList,GTLV_Top,0,TAG_DONE);
  426.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV3_Commands],Ctrl,NULL,GTLV_Labels,BBSGlobal->ButtonName,GTLV_Top,0,TAG_DONE);
  427.   UpdateInfoLists();
  428. }
  429.  
  430. // small routing to check that all the windows on a screen have been closed..
  431.  
  432. void CloseAllWindows(struct Screen *Scr)
  433. {
  434.   if ((Scr) && (Scr->FirstWindow))
  435.   {
  436.     while (Scr->FirstWindow->NextWindow)
  437.     {
  438.       rtEZRequest("Please Close All Windows Before Clicking OK","OK",NULL,NULL,NULL);
  439.     }
  440.   }
  441. }
  442.  
  443. void CloseTheScreen( void )
  444. {
  445.   if (CfgOpen)
  446.   {
  447.     CloseCtrlCfgWindow();
  448.     CfgOpen=FALSE;
  449.   }
  450.   CloseAllWindows(Scr);
  451.  
  452.   if (Ctrl)
  453.   {
  454.     CloseCtrlWindow();
  455.     CtrlProc->pr_WindowPtr=OldWindowPtr;
  456.   }
  457.   if (Scr) CloseScreen(Scr);
  458. }
  459.  
  460. BOOL OpenTheScreen( void )
  461. {
  462.   BOOL Cancel=FALSE;
  463.  
  464.   Ctrl=NULL;
  465.   CfgOpen=FALSE;
  466.  
  467.   do
  468.   {
  469.     if (Scr = OpenCtrlScrn())
  470.     {
  471.       BBSGlobal->scr=Scr;
  472.       PubScreenStatus(Scr,0);
  473.       if (OpenCtrlWindow(Scr)==0)
  474.       {
  475.         // bring screen to front..
  476.         if (!BBSGlobal->HideScreen) ScreenToFront(Scr);
  477.         OldWindowPtr=CtrlProc->pr_WindowPtr;
  478.         CtrlProc->pr_WindowPtr=Ctrl;
  479.         offx = Ctrl->BorderLeft;
  480.         offy = Ctrl->BorderTop;
  481.         updategadgets();
  482.         return(TRUE);
  483.       }
  484.       else HBBS_DoErrorMessage(EMSG_NOWINDOW,0,NULL);
  485.     }
  486.     else HBBS_DoErrorMessage(EMSG_NOSCREEN,0,NULL);
  487.     if (Scr==NULL)
  488.     {
  489.       Cancel=!PickScreen();
  490.     }
  491.   } while (Cancel==FALSE);
  492.  
  493.   CloseTheScreen();
  494.   return(FALSE);
  495. }
  496.  
  497. void ChangeScreenMode( void )
  498. {
  499.   if (AllNodesShut())
  500.   {
  501.     PickScreen();
  502.     CloseTheScreen();
  503.     OpenTheScreen();
  504.   }
  505.   else HBBS_DoErrorMessage(EMSG_CANTCHANGESCREEN,0,NULL);
  506. }
  507.  
  508.  
  509. void UpdateCtrlStatus(V_BIGNUM Flags,V_BIGNUM Value)
  510. {
  511.   switch (Flags)
  512.   {
  513.     case UPD_NODESTATUS:
  514.       switch (Value)
  515.       {
  516.         case STAT_CLOSED:
  517.           strcpy(StatusText,str_STAT_CLOSED);
  518.           break;
  519.         case STAT_LOADING:
  520.           strcpy(StatusText,str_STAT_LOADING);
  521.           break;
  522.         case STAT_INITIALIZING:
  523.           strcpy(StatusText,str_STAT_INITIALIZING);
  524.           break;
  525.         case STAT_READY:
  526.           strcpy(StatusText,str_STAT_READY);
  527.           break;
  528.         case STAT_ONLINE:
  529.           strcpy(StatusText,str_STAT_ONLINE);
  530.           break;
  531.         case STAT_CLOSING:
  532.           strcpy(StatusText,str_STAT_CLOSING);
  533.           break;
  534.         default:
  535.           StatusText[0]=0;
  536.           break;
  537.       }
  538.       break;
  539.   }
  540.  
  541.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_StatusText],Ctrl,NULL,GTTX_Text,StatusText,TAG_DONE);
  542.  
  543.  
  544. /*
  545.   SetAPen(Ctrl->RPort,0); // grey
  546.   RectFill( Ctrl->RPort, 64+1+offx,79+offy,offx+628,79+offy+9);
  547.   SetAPen(Ctrl->RPort,1); // black!
  548.   SetBPen(Ctrl->RPort,0); // grey!
  549.   Move( Ctrl->RPort,64+1+offx,8+78+offy);
  550.   Text( Ctrl->RPort,str,strlen(str));
  551. */
  552. }
  553.  
  554.  
  555. void ClearBBSGlobalData(struct BBSGlobalData *BG )
  556. {
  557.   BG->BBSName=NULL;
  558.   BG->BBSSerial=0;
  559.   BG->BBSLocation=NULL;
  560.   BG->BBSCountry=NULL;
  561.   BG->BBSGroup=NULL;
  562.   BG->BBSNodes=0;
  563.   BG->SysopAccount=NULL;
  564.   BG->Drive=NULL;
  565.   BG->BBSDrive=NULL;
  566.   BG->MinFreeSpace=NULL;
  567.   BG->NoFreeSpaceScript=NULL;
  568.   BG->ButtonName=NULL;
  569.   BG->ButtonCMD=NULL;
  570.   BG->HideScreen=FALSE;
  571.   BG->ErrorLogFile=NULL;
  572.   BG->ScrModeID=0;
  573.   BG->ScrHeight=0;
  574.   BG->ScrWidth=0;
  575.   BG->ScrDepth=0;
  576.   BG->UserDataFileName=NULL;
  577.   BG->NewUserAccessLevel=0;
  578.   BG->MaxUsernameAttempts=0;
  579.   BG->MaxPasswordAttempts=0;
  580.   BG->MinPasswordLength=0;
  581.   BG->Languages=0;
  582.   BG->EditorCMD=NULL;
  583.   BG->LastCalledDate[0]=0;
  584.   BG->LastCalledTime[0]=0;
  585.   BG->CallsToday=0;
  586. }
  587.  
  588. void SetBBSGlobalDefaults(struct BBSGlobalData *BG )
  589. {
  590.   BG->BBSSerial=0;
  591.   FreeAndSet(&BG->BBSLocation,"UnKnown");
  592.   FreeAndSet(&BG->BBSCountry,"UnKnown");
  593.   FreeAndSet(&BG->SysopAccount,"Sysop");
  594.   BG->MinFreeSpace=4096;
  595.   FreeAndSet(&BG->ErrorLogFile,FILE_ERRORLOG);
  596.   BG->ScrModeID=167936; // pal hi-res screen..
  597.   BG->ScrHeight=256;
  598.   BG->ScrWidth=640;
  599.   BG->ScrDepth=2;
  600.   BG->CopyBufferSize=32768; // 32K
  601.  
  602.   FreeAndSet(&BG->UserDataFileName,"HBBS:System/Data/User.Data");
  603.   BG->NewUserAccessLevel=0;
  604.   BG->MaxUsernameAttempts=3;
  605.   BG->MaxPasswordAttempts=3;
  606.   BG->MinPasswordLength=4;
  607. }
  608.  
  609. void FreeBBSGlobalData(struct BBSGlobalData *BG)
  610. {
  611.   FreeStr(BG->BBSName);
  612.   FreeStr(BG->BBSLocation);
  613.   FreeStr(BG->BBSCountry);
  614.   FreeStr(BG->SysopAccount);
  615.   FreeStr(BG->BBSDrive);
  616.   FreeStr(BG->NoFreeSpaceScript);
  617.   FreeStr(BG->ErrorLogFile);
  618.   FreeStr(BG->UserDataFileName);
  619.   FreeStr(BG->EditorCMD);
  620.   FreeStrList(BG->BBSGroup);
  621.   FreeStrList(BG->Drive);
  622.   FreeStrList(BG->ButtonName);
  623.   FreeStrList(BG->ButtonCMD);
  624.   FreeStrList(BG->LanguageName);
  625.   FreeStrList(BG->LanguageExtn);
  626. }
  627.  
  628. V_ERROR LoadBBSGlobalData(char *filename,struct BBSGlobalData *BG )
  629. {
  630.   struct CfgFileData *BBSCFG;
  631.   V_ERROR error=TYPE_NONE;
  632.  
  633.   ClearBBSGlobalData(BG);
  634.   SetBBSGlobalDefaults(BG);
  635.   if (BBSCFG=HBBS_LoadConfig(filename,LCFG_NONE))
  636.   {
  637.     // get settings!
  638.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSNodes,VTYPE_BIGNUM,OPT_BBS_BBSNodes,OPT_SINGLE);
  639.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSName,VTYPE_STRING,OPT_BBS_BBSName,OPT_SINGLE);
  640.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSSerial,VTYPE_BIGNUM,OPT_BBS_BBSSerial,OPT_SINGLE);
  641.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSLocation,VTYPE_STRING,OPT_BBS_BBSLocation,OPT_SINGLE);
  642.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSCountry,VTYPE_STRING,OPT_BBS_BBSCountry,OPT_SINGLE);
  643.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSGroup,VTYPE_STRINGLIST,OPT_BBS_BBSGroup,OPT_MULTI);
  644.     HBBS_GetSetting(BBSCFG,(void *)&BG->SysopAccount,VTYPE_STRING,OPT_BBS_SysopAccount,OPT_SINGLE);
  645.     HBBS_GetSetting(BBSCFG,(void *)&BG->Drive,VTYPE_STRINGLIST,OPT_BBS_Drive,OPT_MULTI);
  646.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSDrive,VTYPE_STRING,OPT_BBS_BBSDrive,OPT_SINGLE);
  647.     HBBS_GetSetting(BBSCFG,(void *)&BG->MinFreeSpace,VTYPE_BIGNUM,OPT_BBS_MinFreeSpace,OPT_SINGLE);
  648.     HBBS_GetSetting(BBSCFG,(void *)&BG->NoFreeSpaceScript,VTYPE_STRING,OPT_BBS_NoFreeSpaceScript,OPT_SINGLE);
  649.     HBBS_GetSetting(BBSCFG,(void *)&BG->ButtonName,VTYPE_STRINGLIST,OPT_BBS_ButtonName,OPT_MULTI);
  650.     HBBS_GetSetting(BBSCFG,(void *)&BG->ButtonCMD,VTYPE_STRINGLIST,OPT_BBS_ButtonCMD,OPT_MULTI);
  651.     HBBS_GetSetting(BBSCFG,(void *)&BG->HideScreen,VTYPE_BOOL,OPT_BBS_HideScreen,OPT_SINGLE);
  652.     HBBS_GetSetting(BBSCFG,(void *)&BG->ErrorLogFile,VTYPE_STRING,OPT_BBS_ErrorLogFile,OPT_SINGLE);
  653. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScrModeID,VTYPE_BIGNUM,OPT_BBS_ScrModeID,OPT_SINGLE);
  654. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScrHeight,VTYPE_BIGNUM,OPT_BBS_ScrHeight,OPT_SINGLE);
  655. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScrWidth,VTYPE_BIGNUM,OPT_BBS_ScrWidth,OPT_SINGLE);
  656. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScrDepth,VTYPE_BIGNUM,OPT_BBS_ScrDepth,OPT_SINGLE);
  657.     HBBS_GetSetting(BBSCFG,(void *)&BG->UserDataFileName,VTYPE_STRING,OPT_BBS_UserDataFileName,OPT_SINGLE);
  658.     HBBS_GetSetting(BBSCFG,(void *)&BG->NewUserAccessLevel,VTYPE_SMALLNUM,OPT_BBS_NewUserAccessLevel,OPT_SINGLE);
  659.     HBBS_GetSetting(BBSCFG,(void *)&BG->MaxUsernameAttempts,VTYPE_SMALLNUM,OPT_BBS_MaxUsernameAttempts,OPT_SINGLE);
  660.     HBBS_GetSetting(BBSCFG,(void *)&BG->MaxPasswordAttempts,VTYPE_SMALLNUM,OPT_BBS_MaxPasswordAttempts,OPT_SINGLE);
  661.     HBBS_GetSetting(BBSCFG,(void *)&BG->MinPasswordLength,VTYPE_SMALLNUM,OPT_BBS_MinPasswordLength,OPT_SINGLE);
  662.     HBBS_GetSetting(BBSCFG,(void *)&BG->LanguageName,VTYPE_STRINGLIST,OPT_BBS_LanguageName,OPT_MULTI);
  663.     BG->Languages=HBBS_GetSetting(BBSCFG,(void *)&BG->LanguageExtn,VTYPE_STRINGLIST,OPT_BBS_LanguageExtn,OPT_MULTI);
  664.     HBBS_GetSetting(BBSCFG,(void *)&BG->EditorCMD,VTYPE_STRING,OPT_BBS_EditorCMD,OPT_SINGLE);
  665.     HBBS_GetSetting(BBSCFG,(void *)&BG->CopyBufferSize,VTYPE_BIGNUM,OPT_BBS_CopyBufferSize,OPT_SINGLE);
  666.  
  667.  
  668.     HBBS_FlushConfig(BBSCFG);
  669.   }
  670.   return(error);
  671. }
  672.  
  673. static VOID cleanup(ULONG num)
  674. {
  675.   CloseLoadingWindow();
  676.  
  677.   if (num)
  678.   {
  679.     if (HBBSCommonBase) HBBS_DoErrorMessage(num,0,NULL);
  680.   }
  681.  
  682.   FreeImages();
  683.  
  684.   CloseFont( HBBSFont ) ;
  685.   CloseLibs();
  686.  
  687.   if (HBBSCommonBase)
  688.   {
  689.     HBBS_CleanUpCommon();
  690.     CloseLibrary (HBBSCommonBase);
  691.   }
  692.  
  693.   if (BBSGlobal)
  694.   {
  695.     if (BBSGlobal->CtrlMainPort) DeletePort(BBSGlobal->CtrlMainPort);
  696.     if (BBSGlobal->CtrlMainReplyPort) DeletePort(BBSGlobal->CtrlMainReplyPort);
  697.     if (BBSGlobal->NodeGlobalData) FreeVec(BBSGlobal->NodeGlobalData);
  698.     FreeVec(BBSGlobal);
  699.   }
  700.  
  701.   if (ReqToolsBase)
  702.     CloseLibrary ((struct Library *)ReqToolsBase);
  703.  
  704.   exit(0);
  705. }
  706.  
  707. int OpenTheDiskFonts( void )
  708. {
  709.   int OKSoFar = 1;
  710. if ((HBBSFont = OpenDiskFont( &HBBS8066 )) == NULL )
  711.   OKSoFar = 0;
  712. return ( OKSoFar );
  713. }
  714.  
  715.  
  716. void init(VOID) // will never return anything as if something in here fails the
  717. {               // program is terminated
  718.  
  719.   struct MsgPort *tmpport;
  720.  
  721.   if (OpenLibs())
  722.   {
  723.     cleanup(EMSG_NOLIBS);
  724.   }
  725.   else
  726.   {
  727.     if (!OpenTheDiskFonts())
  728.     {
  729.       cleanup(EMSG_NOFONT);
  730.     }
  731.     else
  732.     {
  733.       if (!MakeImages())
  734.       {
  735.         if (!(ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
  736.         {
  737.           cleanup(EMSG_NOREQTOOLS);
  738.         }
  739.  
  740.         if(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0))
  741.         {
  742.           if (HBBS_InitCommon())
  743.           {
  744.  
  745.  
  746.             Forbid();
  747.             tmpport=FindPort(CtrlMainPortName);
  748.             Permit();
  749.  
  750.             if (tmpport)
  751.               cleanup(EMSG_ALREADYSTARTED);
  752.  
  753.             if (BBSGlobal=(struct BBSGlobalData*) AllocVec(sizeof(struct BBSGlobalData),MEMF_PUBLIC|MEMF_CLEAR))
  754.             {
  755.               if (BBSGlobal->NodeGlobalData=(struct NodeData*) AllocVec(sizeof(struct NodeData),MEMF_PUBLIC|MEMF_CLEAR))
  756.               {
  757.                 if (BBSGlobal->CtrlMainPort=CreatePort(CtrlMainPortName,0))
  758.                 {
  759.                   if (BBSGlobal->CtrlMainReplyPort=CreatePort(0,0))
  760.                   {
  761.                     // *C* move this line to just before the nodes start..
  762.                     // then all the data will be ready for all external doors to use..
  763.                     HBBS_SetBBS(BBSGlobal);
  764.                     return;
  765.                   }
  766.                 }
  767.               }
  768.             }
  769.           }
  770.         }
  771.       }
  772.       cleanup(EMSG_NOMEM);
  773.     }
  774.   }
  775. }
  776.  
  777. void RequestNode(struct NodeData *ND,V_BIGNUM status)
  778. {
  779.   struct StatusMsg *SMsg;
  780.  
  781.   // memory will be free'd by NODE program (if node is alive of course!)
  782.   if (SMsg=(struct StatusMsg *)AllocVec(sizeof(struct StatusMsg),MEMF_PUBLIC))
  783.   {
  784.     SMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  785.     SMsg->message.mn_ReplyPort=NULL;  // must set to null!
  786.     SMsg->message.mn_Length=sizeof(struct StatusMsg);
  787.     SMsg->MsgType=mtype_STATUS;
  788.     SMsg->Status=status;
  789.     SendMessage((struct Message*)SMsg,ND->PortName);
  790.   }
  791. }
  792.  
  793. // Main Routine to close down a node.
  794.  
  795. void StopNode(short nodenum)
  796. {
  797.   struct NodeData *nd;
  798.  
  799.   if (nd=HBBS_NodeDataPtr(nodenum))
  800.   {
  801.     RequestNode(nd,STAT_REQUESTCLOSE);
  802.   }
  803. }
  804.  
  805. void StartNode(short nodenum)
  806. {
  807.   struct NodeData *nd;
  808.   static ULONG sysargs[] =
  809.   {
  810.     SYS_Input,NULL,
  811.     SYS_Output,NULL,
  812.     SYS_Asynch,TRUE,
  813.     SYS_UserShell,TRUE,
  814.     NP_Priority,0L,
  815.     TAG_DONE
  816.   };
  817.   BPTR outputfile;
  818.   BOOL ok=FALSE;
  819.   char command[100]; // *C* Change me!!! :-)
  820.  
  821.   if (nd=HBBS_NodeDataPtr(nodenum))
  822.   {
  823.     if (nd->Status==STAT_CLOSED) // check to see if node is already open first.
  824.     {
  825.       nd->Status=STAT_LOADING;
  826.       UpdateCtrlStatus(UPD_NODESTATUS,nd->Status);
  827.  
  828. #ifndef DEBUGNODE
  829.       if (outputfile = Open(str_CONSOLE,MODE_OLDFILE))
  830.       {
  831.         sysargs[1]=(ULONG)outputfile;
  832.         sprintf(command,"HBBS:Doors/System/Node %d",nodenum);
  833.  
  834.         if (SystemTagList(command,(struct TagItem *)sysargs)==0)
  835.         {
  836.           ok=TRUE;
  837.         }
  838.       }
  839.       if (!ok)
  840.       {
  841.         nd->Status=STAT_CLOSED;
  842.         HBBS_LogError(FILE_ERRORLOG,ERR_GENERAL,"Error Starting Node!",TYPE_CRITICAL);
  843.       }
  844. #else
  845.       rtEZRequest("Start Node Program NOW!","OK!",NULL,NULL,NULL);
  846. #endif
  847.     }
  848.   }
  849. }
  850.  
  851. // only called once, this just starts all the nodes that have autostart enabled!
  852.  
  853. void StartNodes( void )
  854. {
  855.   struct NodeData *nd;
  856.  
  857.   for (nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd = (struct NodeData*)nd->node.ln_Succ)
  858.   {
  859.     if (nd->AutoStart) StartNode(nd->NodeNum);
  860.   }
  861. }
  862.  
  863. void StopAllNodes( void )
  864. {
  865.   struct NodeData *nd;
  866.  
  867.   for (nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd = (struct NodeData*)nd->node.ln_Succ)
  868.   {
  869.     // if node is not busy then tell it to shutdown..
  870.     if (nd->Status==STAT_READY) StopNode(nd->NodeNum);
  871.   }
  872. }
  873.  
  874. void HandleStatusMsg( struct StatusMsg *SMsg )
  875. {
  876.   struct NodeData *nd;
  877.  
  878.   if (nd=HBBS_NodeDataPtr(SMsg->NodeNum))
  879.   {
  880.     GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,nd->NodeNum,TAG_DONE);
  881. #ifdef KS20
  882.     LastNodeClicked=SMsg->NodeNum;
  883. #endif
  884.     // get the nodestatus node and set the status variable
  885.     // actually the NODE program could do this but the control program would not be
  886.     // aware, so we send a msg.. :-)
  887.  
  888.     nd->Status=SMsg->Status;
  889.  
  890.     UpdateCtrlStatus(UPD_NODESTATUS,nd->Status);
  891.  
  892.     if (nd->Status==STAT_CLOSED)
  893.     {
  894.       StopNode(SMsg->NodeNum);
  895.       GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,NULL,TAG_DONE);
  896.     }
  897.   }
  898.   // reply wanted ??
  899.   if (SMsg->message.mn_ReplyPort)
  900.   {
  901.     // yup, reply it then..
  902.     ReplyMsg((struct Message *)SMsg);
  903.   }
  904.   else
  905.   {
  906.     // nope, free the mem..
  907.     FreeVec(SMsg);
  908.   }
  909. }
  910.  
  911. void HandleAskMsg(struct AskMsg *AMsg)
  912. {
  913.   switch (AMsg->Flags)
  914.   {
  915.     case ASK_BBSGLOBAL:
  916.       AMsg->Pointer=(void *)BBSGlobal;
  917.       break;
  918.     default:
  919.       puts("UnKnown AskMsg Received!");
  920.       break;
  921.   }
  922.   ReplyMsg((struct Message *)AMsg);
  923. }
  924.  
  925. void HandleRequestMsg(struct RequestMsg *RMsg)
  926. {
  927.   switch (RMsg->Flags)
  928.   {
  929.     case REQ_UPDATEINFO:
  930.       UpdateInfoLists();
  931.       break;
  932.     default:
  933.       puts("UnKnown RequestMsg Received!");
  934.       break;
  935.   }
  936.   ReplyMsg((struct Message *)RMsg);
  937. }
  938.  
  939. // the message handler!
  940.  
  941. void HandleMsg(void )
  942. {
  943.   struct NodeMsg *Msg;
  944.  
  945.   while (Msg=(struct NodeMsg *)GetMsg(BBSGlobal->CtrlMainPort))
  946.   {
  947.     switch (Msg->MsgType)
  948.     {
  949.       case mtype_ASK:
  950.         HandleAskMsg((struct AskMsg *)Msg);
  951.         break;
  952.       case mtype_STATUS:
  953.         HandleStatusMsg((struct StatusMsg *)Msg);
  954.         break;
  955.       case mtype_REQUEST:
  956.         HandleRequestMsg((struct RequestMsg *)Msg);
  957.         break;
  958.       default:
  959.         puts("UnKnown Message Type!");
  960.         break;
  961.     }
  962.   }
  963. }
  964.  
  965. BOOL CheckDoubleClick(WORD MouseX,WORD MouseY,LONG sec,LONG mic)
  966. {
  967.   if (DoubleClick(last_sec,last_mic,sec,mic) && (MouseX==last_x && MouseY==last_y))
  968.   {
  969.     // clear values so we can doubleclick and doubleclick again without it recognising 3 clicks as being 2 doubleclicks..
  970.     last_x=0;
  971.     last_y=0;
  972.     last_sec=0;
  973.     last_mic=0;
  974.     return(TRUE);
  975.   }
  976.   last_x=MouseX;
  977.   last_y=MouseY;
  978.   last_sec=sec;
  979.   last_mic=mic;
  980.   return(FALSE);
  981. }
  982.  
  983. /* Menu Processing for CtrlMenu */
  984. /* Just pass the code field from an IDCMP_MENUPICK or IDCMP_MENUHELP message. */
  985.  
  986. short ProcessMenuIDCMPCtrlMenu( UWORD MenuNumber)
  987. {
  988.   UWORD MenuNum;
  989.   UWORD ItemNumber;
  990.   UWORD SubNumber;
  991.   short Done=0;           /* Set Done to 1 to forget rest of next selects. */
  992.   short Quit=0;
  993.   struct MenuItem *item;
  994.  
  995.   while ((MenuNumber != MENUNULL) && (Done == 0))
  996.   {
  997.     item = ItemAddress( CtrlMenu, MenuNumber);
  998.     MenuNum = MENUNUM(MenuNumber);
  999.     ItemNumber = ITEMNUM(MenuNumber);
  1000.     SubNumber = SUBNUM(MenuNumber);
  1001.     switch ( MenuNum )
  1002.     {
  1003.       case NOMENU :
  1004.         /* No Menu Selected. */
  1005.         break;
  1006.       case Menu_1 :
  1007.         switch ( ItemNumber )
  1008.         {
  1009.           case NOITEM :
  1010.             /* No Item selcted. */
  1011.             break;
  1012.           case CtrlMenu_About :
  1013.             /* Item Text : About */
  1014.             About();
  1015.             break;
  1016.           case CtrlMenu_ScreenMode :
  1017.             /* Item Text : Screen Mode */
  1018.             Done=1;
  1019.             ChangeScreenMode();
  1020.             break;
  1021.           case bar :
  1022.             /* Item Text : bar */
  1023.             break;
  1024.           case CtrlMenu_Qui :
  1025.             /* Item Text : Quit! */
  1026.             Done=1;
  1027.             Quit=1;
  1028.             break;
  1029.         }
  1030.         break;
  1031.     }
  1032.     if (!Done) MenuNumber = item->NextSelect;
  1033.   }
  1034.   return(Quit);
  1035. }
  1036.  
  1037. short ProcessWindowCtrl( LONG Class, UWORD Code, APTR IAddress, WORD MouseX, WORD MouseY, LONG Seconds, LONG Micros)
  1038. {
  1039.   #ifdef KS30
  1040.     LONG num;
  1041.   #endif
  1042.  
  1043.   char tmpstr[1024],filename[1024];
  1044.   struct NodeData *tempnode;
  1045.   struct Gadget *gad;
  1046.   struct NodeData *nd;
  1047.   short done=0;
  1048.   switch ( Class )
  1049.   {
  1050.     case IDCMP_MENUPICK:
  1051.       done=ProcessMenuIDCMPCtrlMenu(Code);
  1052.       break;
  1053.     case IDCMP_GADGETUP :
  1054.       /* Gadget message, gadget = gad. */
  1055.       gad = (struct Gadget *)IAddress;
  1056.       switch ( gad->GadgetID )
  1057.       {
  1058.         case Ctrl_LV1 :
  1059.           /* ListView pressed, Text of gadget :  */
  1060.           break;
  1061.         case Ctrl_LV1_Cycle :
  1062.           /* Cycle changed   , Text of gadget :  */ // *C* won't work is KS30 is defined..
  1063.           LastCycleClicked=Code;
  1064.           UpdateInfoLists();
  1065.  
  1066.           break;
  1067.         case Ctrl_LV1_Info :
  1068.           /* Button pressed  , Text of gadget : Information */
  1069.           break;
  1070.         case Ctrl_LV2_Nodes :
  1071.           /* ListView pressed, Text of gadget :  */
  1072.           if (Code>=0)
  1073.           {
  1074. #ifdef KS20
  1075.             LastNodeClicked=Code; // cos 2.04 is lAmE
  1076. #endif
  1077.             if (nd=HBBS_NodeDataPtr(Code)) // code contains number of listview selected
  1078.             {
  1079.               UpdateCtrlStatus(UPD_NODESTATUS,nd->Status);
  1080.               UpdateInfoLists();
  1081.  
  1082.               // right, if it's been double clicked then open the node if it's
  1083.               // currenty closed, if it's open then open it's screen..
  1084.  
  1085.               if (CheckDoubleClick(MouseX,MouseY,Seconds,Micros))
  1086.               {
  1087.                 switch(nd->Status)
  1088.                 {
  1089.                   case STAT_CLOSED:
  1090.                     StartNode(nd->NodeNum);
  1091.                     break;
  1092.                   case STAT_READY:
  1093.                   case STAT_ONLINE:
  1094.                     RequestNode(nd,STAT_OPENSCREEN);
  1095.                     break;
  1096.                 }
  1097.               }
  1098.             }
  1099.           }
  1100.           break;
  1101.         case Ctrl_Window :
  1102.           /* Button pressed  , Text of gadget : Callers */
  1103. #ifdef KS30
  1104.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1105.           {
  1106.             if (num>=0)
  1107.             {
  1108.               if (nd=HBBS_NodeDataPtr(num))
  1109.               {
  1110.                 if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1111.                 {
  1112.                   if (nd->NodeSettings.Iconified) RequestNode(nd,STAT_OPENWINDOW); else RequestNode(nd,STAT_CLOSEWINDOW);
  1113.                 }
  1114.               }
  1115.             }
  1116.           }
  1117. #else
  1118.           if (nd=HBBS_NodeDataPtr(LastNodeClicked))
  1119.           {
  1120.             if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1121.             {
  1122.               if (nd->NodeSettings.Iconified) RequestNode(nd,STAT_OPENWINDOW); else RequestNode(nd,STAT_CLOSEWINDOW);
  1123.             }
  1124.           }
  1125. #endif
  1126.           break;
  1127.         case Ctrl_Screen :
  1128.           /* Button pressed  , Text of gadget : Screen */
  1129. #ifdef KS30
  1130.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1131.           {
  1132.             if (num>=0)
  1133.             {
  1134.               if (nd=HBBS_NodeDataPtr(num))
  1135.               {
  1136.                 if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1137.                 {
  1138.                   if (nd->ConOK==FALSE) RequestNode(nd,STAT_OPENSCREEN); else RequestNode(nd,STAT_CLOSESCREEN);
  1139.                 }
  1140.               }
  1141.             }
  1142.           }
  1143. #else
  1144.           if (nd=HBBS_NodeDataPtr(LastNodeClicked))
  1145.           {
  1146.             if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1147.             {
  1148.               if (nd->ConOK==FALSE) RequestNode(nd,STAT_OPENSCREEN); else RequestNode(nd,STAT_CLOSESCREEN);
  1149.             }
  1150.           }
  1151. #endif
  1152.           break;
  1153.         case Ctrl_Stop :
  1154.           /* Button pressed  , Text of gadget : Stop */
  1155. #ifdef KS30
  1156.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1157.           {
  1158.             if (num>=0)
  1159.             {
  1160.               StopNode(num);
  1161.             }
  1162.           }
  1163. #else
  1164.           StopNode(LastNodeClicked);
  1165. #endif
  1166.           break;
  1167.         case Ctrl_Start :
  1168.           /* Button pressed  , Text of gadget : Start */
  1169. #ifdef KS30
  1170.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1171.           {
  1172.             if (num>=0)
  1173.             {
  1174.               StartNode(num);
  1175.             }
  1176.           }
  1177. #else
  1178.           StartNode(LastNodeClicked);
  1179. #endif
  1180.           break;
  1181.         case Ctrl_Config : // node config..
  1182.           /* Button pressed  , Text of gadget : Config */
  1183.  
  1184.           tempnode=HBBS_NodeDataPtr(LastNodeClicked);
  1185.           sprintf(filename,"%sNodeLocal",tempnode->NodeLocation);
  1186.           strcpy(tmpstr,BBSGlobal->EditorCMD);
  1187.           replace(tmpstr,tmpstr,"{FILE}",filename);
  1188.           HBBS_RunDOSCMD(tmpstr,TRUE);
  1189.  
  1190.           break;
  1191.         case Ctrl_Configure : // open config window..
  1192.           if (!CfgOpen)
  1193.           {
  1194.             if (OpenCtrlCfgWindow()==0)
  1195.             {
  1196.               CfgOpen=TRUE;
  1197.             }
  1198.           }
  1199.           /* Button pressed  , Text of gadget : Configure */
  1200.           break;
  1201.         case Ctrl_Shutdown :
  1202.           /* Button pressed  , Text of gadget : Shutdown All */
  1203.           StopAllNodes();
  1204.           break;
  1205.         case Ctrl_LV3_Commands :
  1206.           if (CheckDoubleClick(MouseX,MouseY,Seconds,Micros))
  1207.           {
  1208.             strcpy(tmpstr,HBBS_ListName(BBSGlobal->ButtonCMD,Code));
  1209.             if ((tmpstr[0]) && (stricmp(tmpstr,"SEPERATOR")!=0))
  1210.             {
  1211.               HBBS_RunDOSCMD(tmpstr,TRUE);
  1212.             }
  1213.             // HandleButtonCMD(Code);
  1214.           }
  1215.           break;
  1216.       }
  1217.       break;
  1218.     case IDCMP_CLOSEWINDOW :
  1219.       /* CloseWindow Now */
  1220.       // Stop All The Nodes..
  1221.       StopAllNodes();
  1222.       if (AllNodesShut()) done=1;
  1223.       break;
  1224.     case IDCMP_REFRESHWINDOW :
  1225.       GT_BeginRefresh( Ctrl);
  1226.       /* Refresh window. */
  1227.       RendWindowCtrl( Ctrl, CtrlVisualInfo );
  1228.       GT_EndRefresh( Ctrl, TRUE);
  1229.       GT_RefreshWindow( Ctrl, NULL);
  1230.       RefreshGList( CtrlGList, Ctrl, NULL, ~0);
  1231.       break;
  1232.     case IDCMP_VANILLAKEY :
  1233.       printf("V %d %c\n",Code,Code);
  1234.       break;
  1235.     case IDCMP_RAWKEY :
  1236.       printf("R %d %c\n",Code,Code);
  1237.       break;
  1238.   }
  1239.   return(done);
  1240. }
  1241.  
  1242. void ProcessWindowCtrlCfg( LONG Class, UWORD Code, APTR IAddress )
  1243. {
  1244. struct Gadget *gad;
  1245. char tmpstr[1024];
  1246.  
  1247. switch ( Class )
  1248.   {
  1249.   case IDCMP_GADGETUP :
  1250.     /* Gadget message, gadget = gad. */
  1251.     gad = (struct Gadget *)IAddress;
  1252.     switch ( gad->GadgetID )
  1253.       {
  1254.       case CtrlCfg_ScreenMode :
  1255.         /* Button pressed  , Text of gadget : Pick Mode */
  1256.         ChangeScreenMode();
  1257.         break;
  1258.       case CtrlCfg_EditBBSConfig :
  1259.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  1260.         replace(tmpstr,tmpstr,"{FILE}","HBBS:BBSGlobal");
  1261.         HBBS_RunDOSCMD(tmpstr,TRUE);
  1262.         break;
  1263.       case CtrlCfg_Save :
  1264.         /* Button pressed  , Text of gadget : Save */
  1265.         SaveScreenPrefs();
  1266.         break;
  1267.       }
  1268.     break;
  1269.   case IDCMP_CLOSEWINDOW :
  1270.     /* CloseWindow Now */
  1271.     CloseCtrlCfgWindow();
  1272.     CfgOpen=FALSE;
  1273.     break;
  1274.   case IDCMP_REFRESHWINDOW :
  1275.     GT_BeginRefresh( CtrlCfg);
  1276.     /* Refresh window. */
  1277.   RendWindowCtrlCfg( CtrlCfg, CtrlCfgVisualInfo );
  1278.     GT_EndRefresh( CtrlCfg, TRUE);
  1279.   GT_RefreshWindow( CtrlCfg, NULL);
  1280.   RefreshGList( CtrlCfgGList, CtrlCfg, NULL, ~0);
  1281.     break;
  1282.   }
  1283. }
  1284.  
  1285. void mainloop( void )
  1286. {
  1287.   int done=0;
  1288.   ULONG class;
  1289.   WORD mousex,mousey;
  1290.   LONG secs,mics;
  1291.   UWORD code;
  1292.   struct Gadget *pgsel;
  1293.   struct IntuiMessage *imsg;
  1294.   ULONG ReturnedSig,CfgSig;
  1295.  
  1296.   while(done==0)
  1297.   {
  1298.     CfgSig=CfgOpen ? 1L <<CtrlCfg->UserPort->mp_SigBit : 0L;
  1299.  
  1300.     ReturnedSig=Wait(1L << Ctrl->UserPort->mp_SigBit |  1L << BBSGlobal->CtrlMainPort->mp_SigBit | CfgSig);
  1301.  
  1302.     if (ReturnedSig & 1L << Ctrl->UserPort->mp_SigBit)
  1303.     {
  1304.       while (imsg=GT_GetIMsg(Ctrl->UserPort))
  1305.       {
  1306.         // Copy the bits we need..
  1307.         class=imsg->Class;
  1308.         code=imsg->Code;
  1309.         mousex=imsg->MouseX;
  1310.         mousey=imsg->MouseY;
  1311.         secs=imsg->Seconds;
  1312.         mics=imsg->Micros;
  1313.         pgsel=(struct Gadget *)imsg->IAddress; /* Only reference if it is a gadget message */
  1314.         GT_ReplyIMsg(imsg);
  1315.  
  1316.         done=ProcessWindowCtrl(class, code, pgsel,mousex,mousey,secs,mics);
  1317.       }
  1318.     }
  1319.     if ((CfgOpen) && (ReturnedSig & CfgSig))
  1320.     {
  1321.       while ((CfgOpen) && (imsg=GT_GetIMsg(CtrlCfg->UserPort)))
  1322.       {
  1323.         class=imsg->Class;
  1324.         code=imsg->Code;
  1325.         pgsel=(struct Gadget *)imsg->IAddress;
  1326.         GT_ReplyIMsg(imsg);
  1327.  
  1328.         ProcessWindowCtrlCfg(class, code, pgsel);
  1329.       }
  1330.     }
  1331.  
  1332.     if (ReturnedSig & 1L << BBSGlobal->CtrlMainPort->mp_SigBit)
  1333.     {
  1334.       HandleMsg();
  1335.     }
  1336.   }
  1337. }
  1338.  
  1339.  
  1340. void CtrlMain(void)
  1341. {
  1342.   if (OpenTheScreen())
  1343.   {
  1344.     StartNodes();
  1345.     CloseLoadingWindow();
  1346.     mainloop();
  1347.     CloseTheScreen();
  1348.   }
  1349. }
  1350.  
  1351. V_BOOL CreateNodeList(void)
  1352. {
  1353.   short loop;
  1354.   struct NodeData *node;
  1355.   V_BOOL retval=TRUE;
  1356.   struct CfgFileData *NodeListCFG;
  1357.   UBYTE *option;
  1358.  
  1359.   if (NodeListCFG=HBBS_LoadConfig(FILE_NODELIST,LCFG_NONE))
  1360.   {
  1361.  
  1362.     if (BBSGlobal->NodeList=HBBS_CreateList())
  1363.     {
  1364.       for (loop=0;loop<BBSGlobal->BBSNodes && retval==TRUE;loop++)
  1365.       {
  1366.         retval=FALSE;
  1367.         // note use of MEMF_CLEAR flag, this will set ALL pointers to NULL so we don't have
  1368.         // to do any more work setting up stuff like node->NodeLocation=NULL;
  1369.  
  1370.         if (node=(struct NodeData*)AllocVec(sizeof(struct NodeData),MEMF_PUBLIC|MEMF_CLEAR))
  1371.         {
  1372.           if (node->node.ln_Name=AllocVec(LEN_NODESTATNAME,MEMF_PUBLIC))
  1373.           {
  1374.             sprintf(node->node.ln_Name,"Node_%d",loop);
  1375.             sprintf(node->PortName,"HBBS_Node_%d",loop); // named for door access
  1376.             node->NodeNum=loop;
  1377.  
  1378.             if (node->DoorList=HBBS_CreateList())
  1379.             {
  1380.               if (node->TaggedFileList=HBBS_CreateList())
  1381.               {
  1382.  
  1383.                 if (node->CurrentLine=AllocVec(LEN_CURRENTLINE,MEMF_PUBLIC))
  1384.                 {
  1385.                   if (node->CurrentLineWrap=AllocVec(LEN_CURRENTLINE,MEMF_PUBLIC))
  1386.                   {
  1387.                     if (node->CharsAllowed=AllocVec(256,MEMF_CLEAR))
  1388.                     {
  1389.                       if (option=AllocVec(strlen(OPT_NODE_Location)+6+1,MEMF_PUBLIC|MEMF_CLEAR))
  1390.                       {
  1391.                         sprintf(option,"%s%d",OPT_NODE_Location,loop);
  1392.                         if (HBBS_GetSetting(NodeListCFG,(void *)&node->NodeLocation,VTYPE_PATH,option,OPT_SINGLE))
  1393.                         {
  1394.                           retval=TRUE; // temporary usage of variable..
  1395.                         } else HBBS_DoErrorMessage(EMSG_NOTENOUGHNL,0,NULL);
  1396.                         FreeVec(option);
  1397.                       }
  1398.                       if ((retval=TRUE) &&(option=AllocVec(strlen(OPT_NODE_AutoStart)+6+1,MEMF_PUBLIC|MEMF_CLEAR)))
  1399.                       {
  1400.                         retval=FALSE;// end of temportary esage..
  1401.                         sprintf(option,"%s%d",OPT_NODE_AutoStart,loop);
  1402.                         if (HBBS_GetSetting(NodeListCFG,(void *)&node->AutoStart,VTYPE_BOOL,option,OPT_SINGLE))
  1403.                         {
  1404.                           // we have to add the node to the list here because
  1405.                           // loadnodesettings will not work without it being in the list of nodes.
  1406.                           // if we fail to load the settings however, the node is removed from the list again
  1407.                           AddTail(BBSGlobal->NodeList,(struct Node*)node);
  1408.                           if (LoadNodeSettingsData(loop,&node->NodeSettings)==TYPE_NONE)
  1409.                           {
  1410.                             retval=TRUE;
  1411.                           }
  1412.                           else
  1413.                           {
  1414.  
  1415.                             Remove((struct Node*)node);
  1416.                           }
  1417.                         } else HBBS_DoErrorMessage(EMSG_NOAUTOSTART,loop,NULL);
  1418.                         FreeVec(option);
  1419.                       }
  1420.                       else retval=FALSE;
  1421.                       HBBS_ResetNodeData(node);
  1422.                     }
  1423.                   }
  1424.                 }
  1425.               }
  1426.             }
  1427.           }
  1428.         }
  1429.       }
  1430.     }
  1431.  
  1432.     HBBS_FlushConfig(NodeListCFG);
  1433.   } else retval=FALSE;
  1434.   return(retval);
  1435. }
  1436.  
  1437. void FreeNode(struct NodeData *nd)
  1438. {
  1439.   if (nd->node.ln_Name) FreeVec(nd->node.ln_Name);
  1440.   if (nd->CurrentLine) FreeVec(nd->CurrentLine);
  1441.   if (nd->CurrentLineWrap) FreeVec(nd->CurrentLineWrap);
  1442.   if (nd->CharsAllowed) FreeVec(nd->CharsAllowed);
  1443.   if (nd->NodeLocation)
  1444.   {
  1445.     FreeStr(nd->NodeLocation);
  1446.     nd->NodeLocation=NULL;
  1447.   }
  1448.  
  1449.   if (nd->DoorList)
  1450.   {
  1451.     PrintList(nd->DoorList); // *C* print them out, there is a bug if any are printed!
  1452.     FreeVec(nd->DoorList); // the list should *always* empty at this point
  1453.   }
  1454.   if (nd->TaggedFileList)
  1455.   {
  1456.     FreeVec(nd->TaggedFileList);
  1457.   }
  1458. }
  1459.  
  1460. void FreeNodeList(void)
  1461. {
  1462.   struct NodeData *nd;
  1463.   if (BBSGlobal->NodeList)
  1464.   {
  1465.     while ((nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head) && (nd->node.ln_Succ))
  1466.     {
  1467.       FreeNode(nd);
  1468.       Remove((struct Node *)nd);
  1469.       FreeVec(nd);
  1470.     }
  1471.     FreeVec(BBSGlobal->NodeList);
  1472.   }
  1473. }
  1474.  
  1475. BOOL CreateConfList( void )
  1476. {
  1477.   short loop;
  1478.   struct CfgFileData *ConfListCFG,*ConfCFG;
  1479. //  UBYTE *filename;
  1480.   struct ConfData *NewConf;
  1481.   BOOL error=FALSE;
  1482.   BOOL retval=FALSE;
  1483.   V_STRINGLIST tmplist=NULL;
  1484.   struct Node *tmpnode;
  1485.   UBYTE filename[BIG_STR];
  1486.  
  1487.   BBSGlobal->ConfList=NULL; // initialise so that FreeConfList can decide wether or not to free the list..
  1488.  
  1489.   if (ConfListCFG=HBBS_LoadConfig(FILE_CONFLIST,LCFG_NONE))
  1490.   {
  1491.     HBBS_GetSetting(ConfListCFG,(void *)&BBSGlobal->NewUserConf,VTYPE_BIGNUM,OPT_CONFL_NewUserConf,OPT_SINGLE);
  1492.     HBBS_GetSetting(ConfListCFG,(void *)&BBSGlobal->Conferences,VTYPE_BIGNUM,OPT_CONFL_Conferences,OPT_SINGLE);
  1493.     if ((BBSGlobal->Conferences==HBBS_GetSetting(ConfListCFG,(void *)&tmplist,VTYPE_PATHLIST,OPT_CONFL_ConfPath,OPT_MULTI))
  1494.        && (BBSGlobal->Conferences>0))
  1495.     {
  1496.  
  1497.       if (BBSGlobal->ConfList=HBBS_CreateList())
  1498.       {
  1499.         for (loop=0;loop<BBSGlobal->Conferences && !error ;loop++)
  1500.         {
  1501.           error=TRUE;
  1502.           if (tmpnode=GetNode(tmplist,loop))
  1503.           {
  1504.             if (NewConf=AllocVec(sizeof(struct ConfData),MEMF_PUBLIC|MEMF_CLEAR)) // WARNING: use MEMF_CLEAR here to initialise pointer to NULL
  1505.             {
  1506.  
  1507. //** Removed
  1508. //              if (filename=AllocVec(strlen(tmpnode->ln_Name)+strlen(FILENAME_CONFCONFIG)+1,MEMF_PUBLIC))
  1509. //              {
  1510. //**
  1511.               strcpy(filename,tmpnode->ln_Name);
  1512.               strcat(filename,FILENAME_CONFCONFIG);
  1513.  
  1514.               if (ConfCFG=HBBS_LoadConfig(filename,LCFG_NONE))
  1515.               {
  1516.                 NewConf->ConfPath=DupStr(tmpnode->ln_Name);
  1517.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->node.ln_Name ,VTYPE_STRING     ,OPT_CONF_ConfName      ,OPT_SINGLE);
  1518.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->ConfActive   ,VTYPE_BOOL       ,OPT_CONF_ConfActive    ,OPT_SINGLE);
  1519.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->ConfAccess   ,VTYPE_SMALLNUM   ,OPT_CONF_ConfAccess    ,OPT_SINGLE);
  1520.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->HoldFileList ,VTYPE_STRING     ,OPT_CONF_HoldFileList  ,OPT_SINGLE);
  1521.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->HoldFiles    ,VTYPE_PATHLIST   ,OPT_CONF_HoldFiles     ,OPT_MULTI);
  1522.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->BadFileList  ,VTYPE_STRING     ,OPT_CONF_BadFileList   ,OPT_SINGLE);
  1523.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->BadFiles     ,VTYPE_PATHLIST   ,OPT_CONF_BadFiles      ,OPT_MULTI);
  1524.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->PartUpload      ,VTYPE_PATHLIST   ,OPT_CONF_PartUpload       ,OPT_MULTI);
  1525.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->Upload       ,VTYPE_PATHLIST   ,OPT_CONF_Upload        ,OPT_MULTI);
  1526.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->Download     ,VTYPE_PATHLIST   ,OPT_CONF_Download      ,OPT_MULTI);
  1527.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->MaxDIZLines  ,VTYPE_SMALLNUM   ,OPT_CONF_MaxDIZLines   ,OPT_SINGLE);
  1528.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->MenuPrompt   ,VTYPE_STRING     ,OPT_CONF_MenuPrompt    ,OPT_SINGLE);
  1529.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->AutoMailScan ,VTYPE_BOOL       ,OPT_CONF_AutoMailScan  ,OPT_SINGLE);
  1530.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->ConfPassWD   ,VTYPE_STRING     ,OPT_CONF_ConfPassWD    ,OPT_SINGLE);
  1531.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->UserAllowed  ,VTYPE_STRINGLIST ,OPT_CONF_UserAllowed   ,OPT_MULTI);
  1532.                 NewConf->FileLists=HBBS_GetSetting(ConfCFG,(void *)&NewConf->FileList     ,VTYPE_STRINGLIST ,OPT_CONF_FileList      ,OPT_MULTI);
  1533.  
  1534.                 // *C* check all requires fields are present!
  1535.                 AddTail(BBSGlobal->ConfList,(struct Node*)NewConf);
  1536.                 NewConf->ConfNum=loop+1; // set the conference number
  1537.                 error=FALSE;
  1538.  
  1539.                 HBBS_FlushConfig(ConfCFG);
  1540.               }
  1541.  
  1542. //** Removed
  1543. //                FreeVec(filename);
  1544. //              }
  1545. //**
  1546.             }
  1547.           }
  1548.         }
  1549.         retval=!error; // return TRUE if NO error..
  1550.       }
  1551.     }
  1552.     FreeStrList(tmplist);
  1553.     HBBS_FlushConfig(ConfListCFG);
  1554.   }
  1555.   return(retval);
  1556. }
  1557.  
  1558. void FreeConfList( void )
  1559. {
  1560.   struct ConfData *Conf;
  1561.   if (BBSGlobal->ConfList)
  1562.   {
  1563.     while (BBSGlobal->ConfList->lh_Head->ln_Succ)
  1564.     {
  1565.       Conf=(struct ConfData*)BBSGlobal->ConfList->lh_Head;
  1566.  
  1567.       // free the data..
  1568.  
  1569.       FreeStr(Conf->node.ln_Name);
  1570.       FreeStr(Conf->HoldFileList);
  1571.       FreeStrList(Conf->HoldFiles);
  1572.       FreeStr(Conf->BadFileList);
  1573.       FreeStrList(Conf->BadFiles);
  1574.       FreeStrList(Conf->PartUpload);
  1575.       FreeStrList(Conf->FileList);
  1576.       FreeStrList(Conf->Upload);
  1577.       FreeStrList(Conf->Download);
  1578.       FreeStr(Conf->MenuPrompt);
  1579.       FreeStr(Conf->ConfPassWD);
  1580.       FreeStrList(Conf->UserAllowed);
  1581.       FreeStr(Conf->ConfPath);
  1582.       Remove((struct Node*)Conf);
  1583.       FreeVec(Conf);
  1584.     }
  1585.     FreeVec(BBSGlobal->ConfList);
  1586.   }
  1587. }
  1588.  
  1589. BOOL CheckDirs(struct List *list)
  1590. {
  1591.   struct Node *node;
  1592.   BOOL error=FALSE;
  1593.  
  1594.   // i COULD put && !error in the loop check, but it's more usefull for the sysop
  1595.   // if he/she knows about all the things that are wrong in one go..
  1596.  
  1597.   for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
  1598.   {
  1599.     if (node->ln_Name)
  1600.     {
  1601.       if (!PathOK(node->ln_Name))
  1602.       {
  1603.         error=TRUE;
  1604.         HBBS_DoErrorMessage(EMSG_PATHMISSING,0,node->ln_Name);
  1605.       }
  1606.     }
  1607.   }
  1608.   return((BOOL)!error); // return FALSE if the WAS an error..
  1609. }
  1610.  
  1611. BOOL CheckConfPaths( void )
  1612. {
  1613.   char *str;
  1614.   struct ConfData *Conf;
  1615.   short error=0;
  1616.  
  1617.   for (Conf = (struct ConfData *)BBSGlobal->ConfList->lh_Head ; Conf->node.ln_Succ && error==0 ; Conf =(struct ConfData *)Conf->node.ln_Succ)
  1618.   {
  1619.     if (str=AllocVec(strlen(Conf->ConfPath)+LEN_FILENAME_CONF_LONGEST,MEMF_PUBLIC))
  1620.     {
  1621.       error=2;
  1622.       strcpy(str,Conf->ConfPath);
  1623.       strcat(str,FILENAME_COMMANDS);
  1624.       if (PathOK(str))
  1625.       {
  1626.         strcpy(str,Conf->ConfPath);
  1627.         strcat(str,FILENAME_LOSTFILES);
  1628.         if (PathOK(str))
  1629.         {
  1630.           strcpy(str,Conf->ConfPath);
  1631.           strcat(str,FILENAME_ACCESS);
  1632.           if (PathOK(str))
  1633.           {
  1634.             strcpy(str,Conf->ConfPath);
  1635.             strcat(str,FILENAME_SCREENS);
  1636.             if (PathOK(str))
  1637.             {
  1638.               error=1;
  1639.               if (CheckDirs(Conf->HoldFiles))
  1640.               {
  1641.                 if (CheckDirs(Conf->BadFiles))
  1642.                 {
  1643.                   if (CheckDirs(Conf->PartUpload))
  1644.                   {
  1645.                     error=0;
  1646.                   }
  1647.                 }
  1648.               }
  1649.             }
  1650.           }
  1651.         }
  1652.       }
  1653.       if (error==2) HBBS_DoErrorMessage(EMSG_CONFPATHSERROR,0,NULL);
  1654.       FreeVec(str);
  1655.     }
  1656.   }
  1657.   return((BOOL)(error==0 ? TRUE : FALSE));
  1658. }
  1659.  
  1660. BOOL LoadLevels( void )
  1661. {
  1662.   struct CfgFileData *LevelListFile;
  1663.   BOOL retval=FALSE;
  1664. //  struct Node *node;
  1665.  
  1666.   BBSGlobal->AcsLevelList=NULL;
  1667.   BBSGlobal->AcsLevelNames=NULL;
  1668.  
  1669.   if (LevelListFile=HBBS_LoadConfig(FILE_ACSLEVELLIST,LCFG_NONE))
  1670.   {
  1671.     if (BBSGlobal->AcsLevels=HBBS_GetSetting(LevelListFile,(void *)&BBSGlobal->AcsLevelList,VTYPE_STRINGLIST,OPT_LLIST_LEVEL,OPT_MULTI))
  1672.     {
  1673.       if (BBSGlobal->AcsLevels==HBBS_GetSetting(LevelListFile,(void *)&BBSGlobal->AcsLevelNames,VTYPE_STRINGLIST,OPT_LLIST_LEVELNAME,OPT_MULTI))
  1674.       {
  1675.         // we don't actually load access settings here at all, instead they are loaded for
  1676.         // each conference join and every login
  1677.         retval=TRUE;
  1678.       }
  1679.     }
  1680.     HBBS_FlushConfig(LevelListFile);
  1681.   }
  1682.   else HBBS_DoErrorMessage(EMSG_LEVELSFILEERROR,0,NULL);
  1683.   return(retval);
  1684. }
  1685.  
  1686. void FreeLevels( void )
  1687. {
  1688.   if (BBSGlobal->AcsLevelList) FreeStrList(BBSGlobal->AcsLevelList);
  1689.   if (BBSGlobal->AcsLevelNames) FreeStrList(BBSGlobal->AcsLevelNames);
  1690. }
  1691.  
  1692. BOOL LoadProtocols( void )
  1693. {
  1694.   struct CfgFileData *ProtocolListFile;
  1695.   struct ProtocolNode *pnode;
  1696.   BOOL error=FALSE;
  1697.   char *tmpstr=NULL;
  1698.   char optionname[BIG_STR]="Name_1";
  1699.   int num=1;
  1700.  
  1701.  
  1702.   // Load Config File..
  1703.  
  1704.   if (ProtocolListFile=HBBS_LoadConfig(FILE_PROTOCOLLIST,LCFG_NONE))
  1705.   {
  1706.     // Allocate List..
  1707.  
  1708.     if (BBSGlobal->ProtocolList=HBBS_CreateList())
  1709.     {
  1710.  
  1711.       // Find Protocol Info..
  1712.  
  1713.       while ((!error) && (HBBS_GetSetting(ProtocolListFile,(void *)&tmpstr,VTYPE_STRING,optionname,OPT_SINGLE)))
  1714.       {
  1715.         error=TRUE;
  1716.  
  1717.         // Allocate Protocol Node and get the rest of the settings..
  1718.  
  1719.         if (pnode=AllocVec(sizeof(struct ProtocolNode),MEMF_PUBLIC|MEMF_CLEAR)) // to NULL all variables!
  1720.         {
  1721.           if (pnode->node.ln_Name=DupStr(tmpstr))
  1722.           {
  1723.             FreeStr(tmpstr);
  1724.             tmpstr=NULL;
  1725.             // *C* add checking for missing items!
  1726.  
  1727.             sprintf(optionname,"Type_%d",num);
  1728.             HBBS_GetSetting(ProtocolListFile,(void *)&tmpstr,VTYPE_STRING,optionname,OPT_SINGLE);
  1729.             if (stricmp(tmpstr,"UNIDIRECTIONAL")==0) pnode->protocoltype=PTYPE_UNIDIRECTIONAL;
  1730.             if (stricmp(tmpstr,"BIDIRECTIONAL")==0) pnode->protocoltype=PTYPE_BIDIRECTIONAL;
  1731.             FreeStr(tmpstr);
  1732.             tmpstr=NULL;
  1733.  
  1734.             sprintf(optionname,"ModuleName_%d",num);
  1735.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->modulename,VTYPE_STRING,optionname,OPT_SINGLE);
  1736.  
  1737.             sprintf(optionname,"ModuleOpts_%d",num);
  1738.             if (HBBS_GetSetting(ProtocolListFile,(void *)&pnode->moduleopts,VTYPE_STRING,optionname,OPT_SINGLE)==0)
  1739.             {
  1740.               if (pnode->moduleopts=AllocVec(1,MEMF_PUBLIC))
  1741.               {
  1742.                 pnode->moduleopts[0]=0; // Null Terminated String so that string output
  1743.                                         // routines still work..
  1744.               }
  1745.             }
  1746.  
  1747.             sprintf(optionname,"AllowUL_%d",num);
  1748.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->allow_ul,VTYPE_BOOL,optionname,OPT_SINGLE);
  1749.  
  1750.             sprintf(optionname,"AllowDL_%d",num);
  1751.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->allow_dl,VTYPE_BOOL,optionname,OPT_SINGLE);
  1752.  
  1753.             sprintf(optionname,"AllowBatch_%d",num);
  1754.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->allow_batch,VTYPE_BOOL,optionname,OPT_SINGLE);
  1755.  
  1756.             // Add Completed protocol node to the list of protocols
  1757.  
  1758.             AddTail(BBSGlobal->ProtocolList,(struct Node *)pnode);
  1759.  
  1760.             num++;
  1761.             sprintf(optionname,"Name_%d",num+1);
  1762.             error=FALSE;
  1763.           }
  1764.         }
  1765.  
  1766.  
  1767.       }
  1768.       // free temp string..
  1769.  
  1770.       FreeStr(tmpstr);
  1771.  
  1772.     }
  1773.  
  1774.     // free config..
  1775.  
  1776.     HBBS_FlushConfig(ProtocolListFile);
  1777.   }
  1778.   else HBBS_DoErrorMessage(EMSG_PROTOCOLSFILEERROR,0,NULL);
  1779.  
  1780.   // Set the amount of protocols loaded
  1781.  
  1782.   BBSGlobal->Protocols=num-1;
  1783.  
  1784.   // if no protocols were loaded the return false!
  1785.   return((BOOL)(BBSGlobal->Protocols ? TRUE : FALSE));
  1786. }
  1787.  
  1788. void FreeProtocols( void )
  1789. {
  1790.   struct ProtocolNode *pnode;
  1791.  
  1792.   if (BBSGlobal->ProtocolList)
  1793.   {
  1794.     while (BBSGlobal->ProtocolList->lh_Head->ln_Succ)
  1795.     {
  1796.       pnode=(struct ProtocolNode *)BBSGlobal->ProtocolList->lh_Head;
  1797.       FreeStr(pnode->node.ln_Name);
  1798.       FreeStr(pnode->modulename);
  1799.       FreeStr(pnode->moduleopts);
  1800.       Remove((struct Node *)pnode);
  1801.       FreeVec(pnode);
  1802.     }
  1803.     FreeVec(BBSGlobal->ProtocolList);
  1804.   }
  1805.  
  1806. }
  1807.  
  1808. BOOL CheckBBSGlobal( void )
  1809. {
  1810.   BOOL retval=TRUE;
  1811.   if (BBSGlobal->BBSName==NULL ||
  1812.       BBSGlobal->BBSNodes==0 ||
  1813.       BBSGlobal->Drive==NULL ||
  1814.       BBSGlobal->BBSDrive==NULL)
  1815.   {
  1816.     HBBS_DoErrorMessage(EMSG_BBSGLOBALERR,0,NULL);
  1817.     retval=FALSE;
  1818.   }
  1819.  
  1820.   if (HBBS_NodesInList(BBSGlobal->ButtonName)!=HBBS_NodesInList(BBSGlobal->ButtonCMD))
  1821.   {
  1822.     FreeStrList(BBSGlobal->ButtonName);
  1823.     BBSGlobal->ButtonName=NULL;
  1824.     FreeStrList(BBSGlobal->ButtonCMD);
  1825.     BBSGlobal->ButtonCMD=NULL;
  1826.  
  1827.   }
  1828.   return(retval);
  1829. }
  1830.  
  1831. BOOL InitGlobal( void )
  1832. {
  1833.   if (LoadBBSGlobalData(FILE_BBSGLOBAL,BBSGlobal)==TYPE_NONE)
  1834.   {
  1835.     if (LoadScreenPrefs())
  1836.     {
  1837.       // *C* check required setting.. also need to check for valid assigns on the drives..
  1838.       // must also check config pairs match up.. (e.g. LanguageName/Extn)
  1839.       if (CheckBBSGlobal())
  1840.       {
  1841.         if (HBBS_FindTotalUsers()>=0)
  1842.         {
  1843.           if (LoadLevels())
  1844.           {
  1845.             if (LoadProtocols())
  1846.             {
  1847.               return(TRUE);
  1848.             }
  1849.           }
  1850.         }
  1851.       }
  1852.     }
  1853.   }
  1854.   return(FALSE);
  1855. }
  1856.  
  1857. void FreeGlobal( void )
  1858. {
  1859.   FreeProtocols();
  1860.   FreeLevels();
  1861.   FreeBBSGlobalData(BBSGlobal);
  1862. }
  1863.  
  1864. BOOL InitNodes( void )
  1865. {
  1866.   // Read Settings to be used as a default for all nodes.
  1867.   if (LoadNodeSettingsData(NODE_GLOBAL,&BBSGlobal->NodeGlobalData->NodeSettings)==TYPE_NONE)
  1868.   {
  1869.     // create list of nodes..
  1870.     if (CreateNodeList())
  1871.     {
  1872.       // *C* we need to check that all the required settings for the node have been
  1873.       // set and to set other values to defaults..
  1874.       return(TRUE);
  1875.     }
  1876.   }
  1877.   FreeNodeSettingsData(&BBSGlobal->NodeGlobalData->NodeSettings);
  1878.  
  1879.   return(FALSE);
  1880. }
  1881.  
  1882. BOOL InitConferences( void )
  1883. {
  1884.   if (CreateConfList())
  1885.   {
  1886.     if (CheckConfPaths()) return(TRUE);
  1887.   }
  1888.   return(FALSE);
  1889. }
  1890.  
  1891. void FreeConferences( void )
  1892. {
  1893.   FreeConfList();
  1894. }
  1895.  
  1896. int main(int argc,char **argv)
  1897. {
  1898.   WB2CLI((struct WBStartup *)argv,4000,DOSBase);  /* so you get the default path! */
  1899.   CtrlProc=(struct Process *)FindTask (NULL); // can this fail ?? :-)
  1900.   init();
  1901.  
  1902.   OpenLoadingWindow();
  1903.   if (AssignOK("HBBS:"))
  1904.   {
  1905.     if (InitGlobal())
  1906.     {
  1907.       if (InitNodes())
  1908.       {
  1909.         HBBS_GetDate(BBSGlobal->LastCalledDate);
  1910.         if (InitConferences())
  1911.         {
  1912.           if (LoadPrivateData())
  1913.           {
  1914.             HBBS_LoadCallsData();
  1915.             CtrlMain();
  1916.             HBBS_SaveCallsData();
  1917.           }
  1918.         }
  1919.       //  HBBS_rterror("Freeing Conferences");
  1920.         FreeConferences();
  1921.     //    HBBS_rterror("Freeing Node Settings Data");
  1922.         FreeNodeSettingsData(&BBSGlobal->NodeGlobalData->NodeSettings);
  1923.       }
  1924.   //    HBBS_rterror("Freeing Nodes");
  1925.       FreeNodeList();
  1926.     }
  1927. //    HBBS_rterror("Freeing Global");
  1928.     FreeGlobal(); // we call FreeGlobal even if InitGlobal fails..
  1929.   }
  1930.   else
  1931.   HBBS_DoErrorMessage(EMSG_NOHBBS,0,NULL);
  1932. //  HBBS_rterror("Cleanup");
  1933.   HBBS_SetBBS(NULL); // so that if the lib is still in memory utils won't work anymore..
  1934.   cleanup(NULL);
  1935. }
  1936.